package com.yu.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.hibernate.validator.internal.util.privilegedactions.GetAnnotationAttribute;
import org.junit.runner.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRange;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitterReturnValueHandler;

import com.fasterxml.jackson.annotation.JsonCreator.Mode;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yu.bean.CategoryExample.Criteria;
import com.yu.bean.Comment;
import com.yu.bean.Info;
import com.yu.bean.InfoDetail;
import com.yu.bean.Msg;
import com.yu.bean.User;
import com.yu.service.CommentService;
import com.yu.service.InfoService;
import com.yu.service.PictureService;
import com.yu.service.TpictureService;

import net.sf.jsqlparser.statement.create.index.CreateIndex;

 /**
 * @author YUjiangpeng
 *controller层
 *
 */
@Controller
public class InfoController {
	
	@Autowired
	InfoService infoService;
	
	@Autowired
	CommentService commentService;
	
	@Autowired
	PictureService pictureService;
	
	@Autowired
	TpictureService tpictureService;
	
	/*============================管理员界面=================================*/
	/**
	 * 仅仅用作跳转的页面
	 * @return
	 */
	@RequestMapping("/adminHome2")
	public String adminHomePage(){
		
		return "adminHome2";
		
	}
	
	/**
	 * Response要想正常工作需要导入jackson包
	 * 查询信息数据(分页查询)
	 * @return
	 */
	
	@ResponseBody //返回json数据
	@RequestMapping("/info")
	public Msg getInfoJson(@RequestParam(value="pn",defaultValue="1") Integer pn){
		
		//引入PageHelper分页插件
		//在查询之前只需要调用，传入页码，以及每页的大小
		PageHelper.startPage(pn, 5);
		//startPage后面紧跟的查询就是一个分页查询
		List<Info> infos = infoService.getAllInfo();
		//使用PageInfo包装查询后的结果      只需要将PageInfo交给页面就行了
		//pageInfo里面封装了详细的分页信息 ,包括我们查询出来的数据，第二个参数是连续显示的页数
		PageInfo<Info> page = new PageInfo<Info>(infos, 5);
		return Msg.success().add("pageInfo", page);
		
	}
	
	//@RequestMapping("/info")
	//从首页过来的时候不一定带参数  如果不带参数默认为1  defaultValue=1
	public String getInfo(@RequestParam(value="pn",defaultValue="1") Integer pn, 
			Model model) {
		//引入PageHelper分页插件
		//在查询之前只需要调用，传入页码，以及每页的大小
		PageHelper.startPage(pn, 5);
		//startPage后面紧跟的查询就是一个分页查询
		List<Info> infos = infoService.getAllInfo();
		//使用PageInfo包装查询后的结果      只需要将PageInfo交给页面就行了
		//pageInfo里面封装了详细的分页信息 ,包括我们查询出来的数据，第二个参数是连续显示的页数
		PageInfo<Info> page = new PageInfo<Info>(infos, 5);
		model.addAttribute("pageInfo",page);
		return "adminHome";
		
	}
	
	/**
	 * 信息保存，添加信息
	 * 1.支持JSR303校验
	 * 2.导入Hibernate-Validator
	 * @return
	 */
	@RequestMapping(value="/info", method=RequestMethod.POST)
	@ResponseBody
	public Msg saveInfo(@Valid Info info, BindingResult result){
		if(result.hasErrors()){
			Map<String, Object> map = new HashMap<>();
			//校验失败，应该返回失败，在模态框中显示失败的错误信息
			List<FieldError> errors = result.getFieldErrors();
			for (FieldError fieldError : errors) {
				System.out.println("错误的字段名："+fieldError.getField());
				System.out.println("错误信息："+fieldError.getDefaultMessage());
				map.put(fieldError.getField(), fieldError.getDefaultMessage());
				
			}
			return Msg.fail().add("errorFields", map);
					
		}else{
			infoService.saveInfo(info);
			return Msg.success();	
		}
		
	
	}
	
	/**
	 * 检验信息title是否可用
	 * @param infoTitle
	 * @return
	 */
	@RequestMapping("/checkInfoTitle")
	@ResponseBody
	public Msg checkInfoTitle(@RequestParam("infoTitle")String infoTitle){
		//先判断信息title是否合法
		String regx = "^[\\s\\S]{1,60}$";
		if (!infoTitle.matches(regx)) {
			return Msg.fail().add("regx_msg", "标题必须为1-60位之间！");
		}
		//数据库重复校验
		Boolean b = infoService.checkInfoTitle(infoTitle);
		if(b){
			return Msg.success();
		}else{
		}
		return Msg.fail().add("regx_msg", "标题不可用！");
		
	}
	
	
	/**
	 * 根据id获取信息
	 * @return
	 */
	@RequestMapping(value="/info/{id}", method=RequestMethod.GET)
	@ResponseBody
	//@PathVariable("id") 指定从路径中取出指定id 需要注意前台的请求方式
	public Msg getInfoById(@PathVariable("id") Integer id){
	    Info info	= infoService.getInfoById(id);
		return Msg.success().add("info", info);
		
	}
	
	
	/**
	 * 根据infoId更新信息的内容
	 * @param id
	 * @return
	 * 遇到的问题：网页请求体中有数据但是Info对象封装不进去
	 * update info null null ... where id = xxx
	 * 
	 * 原因：
	 * tomcat:
	 *      1.将请求体中的数据封装成一个map,
	 *      2.request.getParameter("infoTitle")就会从这个map中取值
	 *      3.SpringMVC封装POJO对象的时候
	 *      会把POJO中每个属性的值， request.getParameter("infoTitle");
	 * AJAX发送PUT请求引发的血案：
	 *    PUT请求，请求体中的数据，request.getParameter("infoTitle")拿不到
	 *    Tomcat一看是PUT不会封装请求体中的数据为map,只有POST形式的封装请求体为map   
	 *    
	 *     解决方案：
	 *     我们要能支持直接发送PUT之类的请求还要封装请求体中的数据
	 *     1.配置HttpPutFormContentFilter:
	 *     2.它的作用：将请求体中的数据解析包装成一个map
	 *     3.request被重新包装， request.getParameter()被重写，就会从自己封装的map中取数据
	 */
	
	//由于传入的事实体对象 所以要对应属性名 /info/{id} -> {infoId}
	@RequestMapping(value="/info/{infoId}", method=RequestMethod.PUT)
	@ResponseBody
	public Msg updateInfo(Info info){
		System.out.println("info实体类为**************"+info.getInfoId()+info.getAdId());
		infoService.updateById(info);
		return Msg.success();
		
	}
	
	
	/**
	 * 单个批量删除二合一
	 * 批量删除：1-2-3
	 * 单个删除：1
	 * @return
	 */
	@RequestMapping(value="/info/{ids}", method=RequestMethod.DELETE)
	@ResponseBody
	public Msg deleteInfo(@PathVariable("ids")String ids){
		//批量删除
		if (ids.contains("-")) {
			List<Integer> del_ids = new ArrayList<>();
			String [] str_ids = ids.split("-");
			//组装id的集合
			for (String string : str_ids) {
				del_ids.add(Integer.parseInt(string));
			}
			//批量删除信息前先删除内容图片
			pictureService.deleteConPicsByInfoIds(del_ids);
			System.out.println("删除信息前删除内容图片成功==========0.0");
			//批量删除信息前先删信息标题容图片
			tpictureService.deleteTpicsByInfoIds(del_ids);
			System.out.println("删除信息前删除标题图片成功==========0.0");
			//批量删除信息前先删除对应信息评论的内容
			commentService.deleteCommentByInfoIds(del_ids);
			System.out.println("删除信息前删除评论成功==========0.0");
			
			infoService.deleteBatch(del_ids);
			System.out.println("批量删除信息成功==========0.0");
		}else{
			Integer id = Integer.parseInt(ids);
			//删除信息前删除内容图片
			pictureService.deletConPicByInfoId(id);
			//删除信息前删除标题图片
			tpictureService.deleteTpicByInfoId(id);
			//删除信息前删除评论
			commentService.deletCommentByinfoId(id);
			infoService.deleteInfoById(id);
		}
		
		return Msg.success();
		
	}
	
	
	/*============================用户界面=================================*/
	/**
	 * 跳向未登录主界面
	 * 仅仅用作跳转
	 * @return
	 */
	@RequestMapping("/homePageLink")
	public String homePageLink(@RequestParam(value="pn",defaultValue="1") Integer pn,
			Model model){
		//引入PageHelper分页插件
		//在查询之前只需要调用，传入页码，以及每页的大小
		PageHelper.startPage(pn, 30);
		//startPage后面紧跟的查询就是一个分页查询
		List<Info> infos = infoService.getAllInfoOrderByTime();
		//使用PageInfo包装查询后的结果      只需要将PageInfo交给页面就行了
		//pageInfo里面封装了详细的分页信息 ,包括我们查询出来的数据，第二个参数是连续显示的页数
		PageInfo<Info> page = new PageInfo<Info>(infos, 5);
		model.addAttribute("pageInfo",page);
		model.addAttribute("cate", 0); //用于首页分类区分
		return "homePage";
		
	}
	
	/**
	 * 跳向登录主界面前判断下是否有用户登录，如果没有用户能录则返回未登录主界面
	 * 仅仅用作跳转
	 * @return
	 */
	@RequestMapping("/homePageLoginLink")
	public String homePageLoginLink(@RequestParam(value="pn",defaultValue="1") Integer pn,
			HttpSession session , Model model){
		//进入该接口前判断用户是否登录
		User u = (User)session.getAttribute("u");
		if(u == null){
			return "ulogin";
			//return "redirect:"
		}
		//引入PageHelper分页插件
		//在查询之前只需要调用，传入页码，以及每页的大小
		PageHelper.startPage(pn, 30);
		//startPage后面紧跟的查询就是一个分页查询
		List<Info> infos = infoService.getAllInfoOrderByTime();
		//使用PageInfo包装查询后的结果      只需要将PageInfo交给页面就行了
		//pageInfo里面封装了详细的分页信息 ,包括我们查询出来的数据，第二个参数是连续显示的页数
		PageInfo<Info> page = new PageInfo<Info>(infos, 5);
		model.addAttribute("pageInfo",page);
		model.addAttribute("cate", 0); //用于首页分类区分
		return "homePageLogin";
		
	}
	
	 @RequestMapping("/uInfo")
	//从首页过来的时候不一定带参数  如果不带参数默认为1  defaultValue=1
	public String getUinfo(@RequestParam(value="cate", required=true)Integer cate,
	@RequestParam(value="pn",defaultValue="1") Integer pn,
	HttpSession session, Model model) {
		 System.out.println("传入的参数分别为类别======》"+cate+"页数====》"+pn);
		//引入PageHelper分页插件
		//在查询之前只需要调用，传入页码，以及每页的大小
		PageHelper.startPage(pn, 30);
		//startPage后面紧跟的查询就是一个分页查询
		List<Info> infos = infoService.getAllInfoByCate(cate);
		//使用PageInfo包装查询后的结果      只需要将PageInfo交给页面就行了
		//pageInfo里面封装了详细的分页信息 ,包括我们查询出来的数据，第二个参数是连续显示的页数
		PageInfo<Info> page = new PageInfo<Info>(infos, 5);
		model.addAttribute("pageInfo",page);
		if(cate == 0){
			model.addAttribute("cate", 0);
		}else{
			model.addAttribute("cate", cate);
		}
		System.out.println("分页的页数为=======》"+page.getNavigatepageNums());
		User u =(User)session.getAttribute("u");
		if(u != null)
			return "homePageLogin";
		else
			return "homePage";
		
	}
	 
	 /**
	  * 根据infoId获取info详细内容
	 * @return
	 * ("/getInfoDetail/{infoId}")从地址栏中获取参数 注意页面的传参形式
	 */
	@RequestMapping("/getInfoDetail/{infoId}")
	public String getInfoDet(@PathVariable("infoId")Integer infoId, Model m){
		 Info info = infoService.getInfoById(infoId);
		 List <InfoDetail>  indetials = infoService.getInfoDetailById(infoId);
		 //信息
		 m.addAttribute("info", info);
		 //详细信息内容
		 m.addAttribute("indetails", indetials);
		 //所有评论内容
		 List<Comment> coms = commentService.getAllCommentByInfoId(infoId);
		 System.out.println("详细信息==============》为："+coms);
		 m.addAttribute("comments", coms);
		return "detailInfo";
		 
	 }
	
	
	/**
	 * 根据搜索显示对应信息
	 * @param s
	 * @return
	 */
	@RequestMapping(value="/searchInfo", method=RequestMethod.GET)
	public String searchInfo(@RequestParam(value="s", required=true)String s,
			@RequestParam(value="pn",defaultValue="1") Integer pn,
			HttpSession session,Model model){
		//引入PageHelper分页插件
		//在查询之前只需要调用，传入页码，以及每页的大小
		PageHelper.startPage(pn, 30);
		//startPage后面紧跟的查询就是一个分页查询
		List<Info> infos = infoService.searchInfoByCondtion(s);
		//使用PageInfo包装查询后的结果      只需要将PageInfo交给页面就行了
		//pageInfo里面封装了详细的分页信息 ,包括我们查询出来的数据，第二个参数是连续显示的页数
		PageInfo<Info> page = new PageInfo<Info>(infos, 5);
		model.addAttribute("pageInfo",page);
		model.addAttribute("sevl", s);
		model.addAttribute("sear", 1);
		User u =(User)session.getAttribute("u");
		if(u != null)
			return "homePageLogin";
		else
			return "homePage";
		
	}

}
